﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace WCFUtility {


	/// <summary>
	/// MS' original implementation of the channel throws an exception in Dispose when an communication error occurs.
	/// When the  channel is used correctly via using ..... any original exceptions will get lost, use this class to 
	/// avoid this, dispose will catch and ignore exceptions if TimeOutException as well as CommunicationExceptions
	/// </summary>
	public class ProxyReference : IDisposable {
		private ICommunicationObject m_ClientChannel;
		private bool m_Disposed = false;

		public ProxyReference(ICommunicationObject clientChannel) {
			m_ClientChannel = clientChannel;
		}

		~ProxyReference() {
			Dispose(false);
		}

		public void Dispose() {
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing) {
			if (!m_Disposed) {
				if (disposing) {
					try {
						// Assume that ICommunicationObject.Dispose() attempts to close()
						((IDisposable)m_ClientChannel).Dispose();
					} catch (TimeoutException) {
						m_ClientChannel.Abort();
					} catch (CommunicationException) {
						m_ClientChannel.Abort();
					}
				}
			}
			m_Disposed = true;
		}
	}
}
